import configparser
import datetime
import locale

locale.setlocale(locale.LC_ALL,'')

ENCODING = "utf-8"
translation = Import('translation.py')
translation.use('transl_forum.ini')
_ = translation.translate

config = Import('config.py')
topics_store = Import('topics.py')
if config.engine == 'sqlite':
    db = Import('database_sqlite.py').open(config.connection)

# buttons for the whizzywig textarea
ww_buttons ='bold italic underline | left center right justify | '
ww_buttons += 'number bullet indent outdent | undo redo | color hilite rule | '
ww_buttons += 'link image';

# date format
dformat = _('on')+' %x '+_('at time')+' %H:%M'

class Node:

    def __init__(self,**args):
        self.attrs = args
        self.parent = None
        self.children = []

    def __getitem__(self,key):
        return self.attrs[key]

def _head(msg=_("Forum")):
    head = HEAD()
    head <= TITLE(msg)
    head <= LINK(rel="stylesheet",href="../%s.css" %config.theme)
    head <= SCRIPT(src="../forum.js")
    return head

def banner():
    t = TABLE(Class="minimalist")
    row = TR()
    row <= TD(A(_('Home'),href='index'))
    if User():
        row <= TD(User().login+' '+A(_('Logout'),href="logout"),
            style="text-align:right;")
    else:
        row <= TD(A(_('Login'),href="login"),style="text-align:right;")
    t <= row
    t <= TR(TD(config.title,Id="title",colspan=2))

    return t
    
def index(page=1):
    try:
        page = int(page)
    except:
        raise HTTP_REDIRECTION('index')
    topics = topics_store.topics
    last_page = 1+int((len(topics)-1)/config.topics_per_page)
    if page>last_page:
        page=last_page
    elif page<1:
        page=1
    
    body = banner()
    
    form = FORM(action="new_topic")
    form <= INPUT(Type="submit",value=_("Create topic"))

    table = TABLE(Class="minimalist")
    table <= CAPTION(form,style="text-align:left;")
    
    menu_pages = TR()
    cell = A('<<',title=_('first'),href='index?page=1')
    if page>1:
        cell += '&nbsp;'*3+A('<',title=_('previous'),href='index?page=%s' %(page-1))
    menu_pages <= TH(cell,align="left")
    cell = 'Page '
    sel = SELECT(onchange="change_page()",Id="page_num")
    sel.from_list(range(1,last_page+1),use_content=True)
    sel.select(value=page)
    cell += sel
    menu_pages <= TH(cell,align="center",colspan=4)
    cell = ''
    if page<last_page:
        cell += ' '+A('>',title=_('next'),href='index?page=%s' %(page+1))
    cell += '&nbsp;'*3+A('>>',title=_('last'),href='index?page=%s' %last_page)
    menu_pages <= TH(cell,align="right")
    table <= menu_pages
    table <= TR(TH(_("Thread"),rowspan=2)+TH(_("By"),rowspan=2)+
        TH(_("Number of"),colspan=3,Class="inner")+TH(_("Last message"),rowspan=2))
    table <= TR(TH(_('Messages'))+TH(_('Authors'))+TH(_('Visits')))
    for topic in topics[(page-1)*20:page*20]:
        t = db['topics'][topic]
        row = TR()
        row <= TD(A(t['title'],href="view_topic?recid=%s" %topic),Class="title")
        row <= TD(t['author'],width="15%")
        row <= TD(t['nb_messages'],width="3%")
        row <= TD(t['nb_authors'],width="3%")
        row <= TD(t['nb_visits'],width="3%")
        row <= TD(t['last_editor']+BR()+SMALL(t['last_modif'].strftime(dformat)),width="30%")
        table <= row
    body += table
    return HTML(_head()+BODY(body))

def _error(msg):
    return HTML(_head()+BODY(msg))
    
def new_topic(**kw):
    Login(role="edit")
    
    head = _head()
    head <= SCRIPT(src='../whizzywig/whizzywig63.js')
    
    body = banner()
    body += H1(_('Create topic'))
    
    form = FORM(action="save_thread",method="post")
    form <= H2(_('Title'))
    form <= INPUT(name="title",size=50)
    form <= H2(_('Text'))
    form <= TEXTAREA(rows=25,cols=80,name="text",Id="text")
    script = 'btn._f="../whizzywig/icons.png";\n'
    script += 'makeWhizzyWig("text","%s")' %ww_buttons
    form <= SCRIPT(script)
    form <= BR()+INPUT(Type="submit",value=_("Save"),name="subm")
    form <= INPUT(Type="submit",value=_("Cancel"),name="subm")
    body += form
    
    return HTML(head+BODY(body))

def _msg_line(message,t,recid,left=0):
    row = TR()
    line = _('by')+'&nbsp;'+message['author']
    line += ' - '+SMALL(message['created'].strftime(dformat))
    if config.answer_level in ["message","both"]:
        form = FORM(action="add_reply",style="display:inline;")
        form <= INPUT(Type="hidden",name="id_msg",value=message['__id__'])
        if config.answer_level == "both":
            form <= INPUT(Type="hidden",name="id_topic",value=recid)
            form <= INPUT(Type="submit",name="subm",
                value=_('Answer topic'),Class="answer")+'&nbsp;'*5
        form <= INPUT(Type="submit",value=_('Answer this message'),
            Class="answer")
        line += form
    msg_body = message['text']
    row <= TD(DL(DT(line)+DD(P()+msg_body),style="margin-left:%s;" %left),
        Class="title")
    t <= row
    if hasattr(message,'children'):
        for child in message.children:
            _msg_line(child,t,recid,left+30)

def view_topic(recid,page=1):
    recid = int(recid)
    page = int(page)
    index = topics_store.topics.index(recid)
    topic_page = 1+int(index/config.topics_per_page)
    topic = db['topics'][recid]
    
    body = banner()
    msg_per_page = config.messages_per_page
    messages = db['messages'](id_topic=recid)
    nb_pages = int((len(messages)-1)/msg_per_page)
    
    if not len(messages)==topic['nb_messages']:
        db['topics'].update(topic,
            nb_messages=len(messages))
        db['topics'].commit()

    t = TABLE(Class="minimalist")
    menu = TR()
    form = FORM(action='view_topic',Id='pgform',style="display:inline;")
    form <= _('Page')+' '
    form <= INPUT(Type="hidden",name='recid', value=recid)
    s = SELECT(name='page').from_list(range(1,nb_pages+2),use_content=True)
    s.select(content=page)
    s['onChange'] = "document.getElementById('pgform').submit()"
    form <= s

    if page==1:
        arrows = '<<'
    else:
        arrows = A('<<',href='view_topic?recid=%s&page=%s' %(recid,1))
    arrows += '&nbsp;'*3

    if page==1:
        arrows += '<'
    else:
        arrows += A('<',href='view_topic?recid=%s&page=%s' %(recid,page-1))
    arrows += '&nbsp;'*3

    if page==nb_pages+1:
        arrows += '>'
    else:
        arrows += A('>',href='view_topic?recid=%s&page=%s' %(recid,page+1))

    arrows += '&nbsp;'*3
    if page==nb_pages+1:
        arrows += '>>'
    else:
        arrows += A('>>',href='view_topic?recid=%s&page=%s' %(recid,nb_pages+1))

    menu <= TH(form+arrows,style='text-align:left;width:20%;')

    menu <= TH(B(topic['title']),style='text-align:center;')
    
    menu <= TH(A(_('Topics'),href='index?page=%s' %topic_page),
        style='text-align:right;')
    t <= TR(TD(TABLE(menu,Class="topic_header"),colspan=2))

    if config.answer_level == "topic":
        messages.sort(key=lambda x:x['created'])
        messages = messages[(page-1)*msg_per_page:page*msg_per_page]
        for message in messages:
            _msg_line(message,t,recid)
        form = FORM(action='add_reply')
        form <= INPUT(Type="hidden",name="id_topic",value=recid)
        form <= INPUT(Type="submit",name="subm",value=_('Answer'),
            Class="answer_topic")
        t <= TR(TD(form))
    else:
        root = Node(__id__=-1,nb=0)
        def build_tree(node):
            children = [Node(**_msg) for _msg in messages 
                if _msg['id_parent_msg']==node['__id__']]
            children.sort(key=lambda x:x['created'])
            node.children = children
            for child in children:
                build_tree(child)
        build_tree(root)
        children = root.children
        children.sort(key=lambda x:x['created'])
        root.children = children            
    
        for message in root.children:
            _msg_line(message,t,recid)

    body += t

    # update visits
    if 'visits' in COOKIE:
        visits = [int(x) for x in COOKIE['visits'].value.split(',')]
        if not recid in visits:
            SET_COOKIE['visits']=COOKIE['visits'].value+',%s' %recid
            _incr_visits(recid)
    else:
        SET_COOKIE['visits']='%s' %recid
        _incr_visits(recid)
    return HTML(_head()+BODY(body))

def _incr_visits(recid):
    # increment number of visits of topic recid
    topic = db['topics'][recid]
    db['topics'].update(topic,
        nb_visits = topic['nb_visits']+1)
    db['topics'].commit()
    
def add_reply(**kw):
    
    Login(role="edit",origin=THIS.path)
    
    head = _head()
    head <= SCRIPT(src='../whizzywig/whizzywig63.js')

    if 'subm' in kw: # answer topic
        id_topic = int(kw['id_topic'])
        topic = db['topics'][id_topic]

        body = banner()
        body += H1(topic['title'],Class="title")

        form = FORM(action="save_message",method="post")
        form <= INPUT(Type="hidden",name="id_topic",value=id_topic)
        form <= H3(_('Your reply'))
        form <= TEXTAREA(rows=25,cols=80,name="text",Id="text")
        script = 'btn._f="../whizzywig/icons.png";\n'
        script += 'makeWhizzyWig("text","%s")' %ww_buttons
        form <= SCRIPT(script)
        form <= BR()+INPUT(Type="submit",value=_("Save"),name="subm")
        form <= INPUT(Type="submit",value=_("Cancel"),name="subm")
        body += DIV(form,Id="reply")

    elif 'id_msg' in kw:
        id_msg = int(kw['id_msg'])
        msg = db['messages'][id_msg]
        id_topic = msg['id_topic']
        topic = db['topics'][id_topic]

        body = banner()
        body += H1(topic['title'],Class="title")

        post = DL(Id="initial_post")
        post <= DT(msg['author']+'&nbsp;'+_('wrote')+
            ' %s :'%msg['created'].strftime(dformat))
        post <= DD(msg['text'])
        body += post

        form = FORM(action="save_message",method="post")
        form <= INPUT(Type="hidden",name="id_topic",value=id_topic)
        form <= INPUT(Type="hidden",name="id_msg",value=id_msg)
        form <= H3(_('Your reply'))
        form <= TEXTAREA(rows=25,cols=80,name="text",Id="text")
        script = 'btn._f="../whizzywig/icons.png";\n'
        script += 'makeWhizzyWig("text","%s")' %ww_buttons
        form <= SCRIPT(script)
        form <= BR()+INPUT(Type="submit",value=_("Save"),name="subm")
        form <= INPUT(Type="submit",value=_("Cancel"),name="subm")
        body += DIV(form,Id="reply")
    
    return HTML(head+BODY(body))

def save_thread(**kw):
    Login(role="edit")
    if kw['subm'] == _('Cancel'):
        raise HTTP_REDIRECTION('index')
    if not 'title' in kw:
        return _error(_('No title'))
    now = datetime.datetime.now()
    rec_id = db['topics'].insert(title=kw['title'],
        author=User().login,
        created=now,
        last_editor=User().login,
        last_modif=now,
        nb_authors=1,
        nb_messages=1,
        nb_visits=0)
    db['topics'].commit()

    db['messages'].insert(id_topic=rec_id,
        id_parent_msg=-1,
        author=User().login,
        text=kw['text'],
        created=now)
    db['messages'].commit()
    
    topics = topics_store.topics
    topics.insert(0,rec_id)
    topics_store.save(topics)
    raise HTTP_REDIRECTION('index')

def save_message(id_topic,text,subm,id_msg=-1):
    Login(role="edit")
    if subm == _('Cancel'):
        raise HTTP_REDIRECTION('index')
    id_topic = int(id_topic)
    topic = db['topics'][id_topic]
    messages = db['messages'](id_topic=id_topic)
    authors = set(msg['author'] for msg in messages)

    user = User().login
    authors.add(user)
    
    now = datetime.datetime.now()
    db['topics'].update(topic,
        last_editor=user,
        last_modif=now,
        nb_authors=len(authors),
        nb_messages=topic['nb_messages']+1
        )
    db['topics'].commit()

    db['messages'].insert(id_topic=id_topic,
        id_parent_msg=int(id_msg),
        author=user,
        text=text,
        created=now)
    db['messages'].commit()
    
    topics = topics_store.topics
    topics.remove(id_topic)
    topics.insert(0,id_topic)
    topics_store.save(topics)
    raise HTTP_REDIRECTION('index')

def logout():
    Logout()

def login():
    Login(role="edit",origin=THIS.abs_url('index.py/index'))
